#include "SystemConfig.h"

#include <QDebug>
#include <vector>

#include "ConfigManager.h"

SystemConfigManager* SystemConfigManager::instance()
{
    static SystemConfigManager instance;
    return &instance;
}

SystemConfigManager::SystemConfigManager(QObject* parent) : QObject(parent) { loadConfig(); }

bool SystemConfigManager::setConfig(const SystemConfig& config)
{
    // 验证配置
    QString errorMessage;
    if (!validateConfig(config, &errorMessage)) {
        qDebug() << "配置验证失败:" << errorMessage;
        return false;
    }

    m_config = config;

    // 保存到配置文件
    if (saveConfig()) {
        emit configChanged(m_config);
        return true;
    }

    return false;
}

bool SystemConfigManager::loadConfig()
{
    ConfigManager* configManager = ConfigManager::instance();
    configManager->loadConfig();
    QJsonObject jsonObject = configManager->getSection("system_config");

    m_config.scheduled = jsonObject["scheduled"].toInt();
    m_config.zeroCheckIntervalDays = jsonObject["zeroCheckIntervalDays"].toInt();
    m_config.zeroCheckTime = jsonObject["zeroCheckTime"].toInt();
    m_config.stdCheckIntervalDays = jsonObject["stdCheckIntervalDays"].toInt();
    m_config.stdCheckTime = jsonObject["stdCheckTime"].toInt();
    m_config.calibIntervalDays = jsonObject["calibIntervalDays"].toInt();
    m_config.calibTime = jsonObject["calibTime"].toInt();
    m_config.spikeRecoveryIntervalDays = jsonObject["spikeRecoveryIntervalDays"].toInt();
    m_config.spikeRecoveryTime = jsonObject["spikeRecoveryTime"].toInt();
    m_config.cleanIntervalDays = jsonObject["cleanIntervalDays"].toInt();
    m_config.cleanTime = jsonObject["cleanTime"].toInt();

    return true;
}

bool SystemConfigManager::saveConfig()
{
    ConfigManager* configManager = ConfigManager::instance();
    QJsonObject jsonObject;

    jsonObject["scheduled"] = m_config.scheduled;
    jsonObject["zeroCheckIntervalDays"] = m_config.zeroCheckIntervalDays;
    jsonObject["zeroCheckTime"] = m_config.zeroCheckTime;
    jsonObject["stdCheckIntervalDays"] = m_config.stdCheckIntervalDays;
    jsonObject["stdCheckTime"] = m_config.stdCheckTime;
    jsonObject["calibIntervalDays"] = m_config.calibIntervalDays;
    jsonObject["calibTime"] = m_config.calibTime;
    jsonObject["spikeRecoveryIntervalDays"] = m_config.spikeRecoveryIntervalDays;
    jsonObject["spikeRecoveryTime"] = m_config.spikeRecoveryTime;
    jsonObject["cleanIntervalDays"] = m_config.cleanIntervalDays;
    jsonObject["cleanTime"] = m_config.cleanTime;

    configManager->setSection("system_config", jsonObject);
    return configManager->saveConfig();
}

bool SystemConfigManager::validateConfig(const SystemConfig& config, QString* errorMessage)
{
    // 检查时间冲突
    if (!checkTimeConflict(config)) {
        if (errorMessage) {
            *errorMessage = "存在时间冲突，请检查各项任务的执行时间设置";
        }
        return false;
    }

    // 其他验证逻辑可以在这里添加
    // 例如：检查时间范围、间隔天数范围等

    return true;
}

bool SystemConfigManager::checkTimeConflict(const SystemConfig& config)
{
    struct TaskConfig {
        int intervalDays;
        int time;
        QString name;
    };

    std::vector<TaskConfig> tasks = {
        {config.zeroCheckIntervalDays, config.zeroCheckTime, "零点核查"},
        {config.stdCheckIntervalDays, config.stdCheckTime, "标液核查"},
        {config.calibIntervalDays, config.calibTime, "校正标定"},
        {config.spikeRecoveryIntervalDays, config.spikeRecoveryTime, "加标回收"},
        {config.cleanIntervalDays, config.cleanTime, "仪表清洗"}};

    // 检查时间冲突（只检查启用的任务，days > 0）
    for (size_t i = 0; i < tasks.size(); ++i) {
        if (tasks[i].intervalDays == 0) continue;  // 跳过未启用的任务

        for (size_t j = i + 1; j < tasks.size(); ++j) {
            if (tasks[j].intervalDays == 0) continue;  // 跳过未启用的任务

            if (tasks[i].time == tasks[j].time) {
                qDebug() << QString("配置冲突：%1和%2都设置在%3点")
                                .arg(tasks[i].name, tasks[j].name)
                                .arg(tasks[i].time);
                return false;
            }
        }
    }
    return true;
}

bool SystemConfigManager::isScheduled(int hour) const { return m_config.scheduled & (1 << hour); }